package handling.channel;

import client.MapleCharacter;
import client.MapleClient;
import database.DatabaseConnection;
import handling.world.World;
import handling.world.World.Broadcast;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.GroupLayout.ParallelGroup;
import javax.swing.GroupLayout.SequentialGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.LayoutStyle;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
import server.ShutdownServer;
import server.Timer;
import server.Timer.EventTimer;
import server.maps.MapleMap;
import server.maps.MapleMapFactory;
import tools.MaplePacketCreator;
import tools.packet.UIPacket;

public class ServerControl extends JFrame {

    DefaultTableModel tableModel;
    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
    private int count;
    private MapleCharacter player;
    private int minutesLeft = 0;
    private ScheduledFuture<?> ts = null;
    protected static Thread t = null;
    private JButton jButtonUpdateLogin;
    private JButton jButton_ClosedServer;
    private JScrollPane jScrollPane1;
    private JScrollPane jScrollPane2;
    private JTable jTable1;
    private JTextField jTextField1;
    private JTextField jTextField2;
    private JLabel jlablecount;

    public ServerControl() {
        //if (ChannelServer.ServerGUI = true) {
            //JOptionPane.showMessageDialog(this, "已自动开启服务端控制台,请勿中途关闭,会导致服务端关闭!");
        //}
        initComponents();
        WindowMid();
        this.tableModel = ((DefaultTableModel) this.jTable1.getModel());

        setResizable(false);
    }

    public void addPlayerInfo(String pname, String channel, String mapname, String pid) {
        this.lock.writeLock().lock();
        try {
            this.tableModel.addRow(new Object[]{pname, channel, mapname, pid});
            this.count += 1;
            this.jlablecount.setText("在线人数：" + this.count);
        } finally {
            this.lock.writeLock().unlock();
        }
    }

    public void removePlayerInfo(String playername) {
        this.lock.writeLock().lock();
        try {
            for (int i = 0; i < this.tableModel.getRowCount(); i++) {
                String cname = (String) this.tableModel.getValueAt(i, 0);
                if (cname.equals(playername)) {
                    this.tableModel.removeRow(i);
                    this.count -= 1;
                    this.jlablecount.setText("在线人数：" + this.count);
                    break;
                }
            }
        } finally {
            this.lock.writeLock().unlock();
        }
    }

    public void updatePlayerInfo(String playername, String map) {
        this.lock.writeLock().lock();
        try {
            for (int i = 0; i < this.tableModel.getRowCount(); i++) {
                String cname = (String) this.tableModel.getValueAt(i, 0);
                if (cname.equals(playername)) {
                    this.tableModel.setValueAt(map, i, 2);
                    break;
                }
            }
        } finally {
            this.lock.writeLock().unlock();
        }
    }

    private void initComponents() {
        this.jButtonUpdateLogin = new JButton();
        this.jTextField1 = new JTextField();
        this.jlablecount = new JLabel();
        this.jTextField2 = new JTextField();
        this.jButton_ClosedServer = new JButton();
        this.jScrollPane2 = new JScrollPane();
        this.jScrollPane1 = new JScrollPane();
        this.jTable1 = new JTable();

        setDefaultCloseOperation(3);

        this.jButtonUpdateLogin.setText("卡号处理");
        this.jButtonUpdateLogin.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                ServerControl.this.jButtonUpdateLoginActionPerformed(evt);
            }
        });
        this.jTextField1.setText("输入卡号的玩家名");

        this.jlablecount.setText("服务端控制台开启成功");

        this.jTextField2.setText("关闭倒计时(单位 分)");

        this.jButton_ClosedServer.setText("关闭服务端");
        this.jButton_ClosedServer.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                ServerControl.this.jButton_ClosedServerActionPerformed(evt);
            }
        });
        this.jScrollPane1.setAutoscrolls(true);
        this.jScrollPane1.setCursor(new Cursor(0));
        this.jScrollPane1.setEnabled(false);

        this.jTable1.setModel(new DefaultTableModel(new Object[0][], new String[]{"玩家名", "所在频道", "所在地图", "ID"}) {
            //boolean[] canEdit = {false, false, false, false};
            boolean[] canEdit = {true, true, true, true};

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return this.canEdit[columnIndex];
            }
        });
        this.jScrollPane1.setViewportView(this.jTable1);

        this.jScrollPane2.setViewportView(this.jScrollPane1);

        GroupLayout layout = new GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup().addContainerGap(-1, 32767).addComponent(this.jTextField2, -2, 175, -2).addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED).addComponent(this.jButton_ClosedServer).addGap(18, 18, 18).addComponent(this.jTextField1, -2, 175, -2).addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED).addComponent(this.jButtonUpdateLogin, -2, 93, -2).addGap(49, 49, 49)).addGroup(layout.createSequentialGroup().addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(layout.createSequentialGroup().addGap(26, 26, 26).addComponent(this.jlablecount, -2, 131, -2)).addGroup(layout.createSequentialGroup().addContainerGap().addComponent(this.jScrollPane2, -2, 624, -2))).addContainerGap(-1, 32767)));

        layout.setVerticalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup().addContainerGap(15, 32767).addComponent(this.jlablecount).addGap(18, 18, 18).addComponent(this.jScrollPane2, -2, 247, -2).addGap(18, 18, 18).addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(this.jButtonUpdateLogin).addComponent(this.jTextField1, -2, -1, -2).addComponent(this.jButton_ClosedServer).addComponent(this.jTextField2, -2, -1, -2)).addContainerGap(16, 32767)));

        pack();
    }

    private void jButtonUpdateLoginActionPerformed(ActionEvent evt) {
        try {
            String name = this.jTextField1.getText();
            int aid = 0;
            int cid = 0;
            boolean nofind = true;
            if (name.isEmpty()) {
                JOptionPane.showMessageDialog(this, "玩家姓名为空。");
                return;
            }

            for (ChannelServer cs : ChannelServer.getAllInstances()) {
                this.player = cs.getPlayerStorage().getCharacterByName(name);
                if (this.player != null) {
                    aid = this.player.getClient().getAccID();
                    cid = this.player.getId();
                    this.player.Dci();
                    cs.removePlayer(this.player);
                }
                for (MapleMap map : cs.getMapFactory().getMaps().values()) {
                    this.player = map.getCharacterByName(name);
                    if (this.player != null) {
                        aid = this.player.getClient().getAccID();
                        cid = this.player.getId();
                        this.player.Dci();
                        map.removePlayer(this.player);
                    }
                }
            }

            Connection c = DatabaseConnection.getConnection();
            if ((cid <= 0) || (aid <= 0)) {
                PreparedStatement getps = c.prepareStatement("select id,accountid from characters where name = ?");
                getps.setString(1, name);
                ResultSet rs = getps.executeQuery();
                if (rs.next()) {
                    cid = rs.getInt("id");
                    aid = rs.getInt("accountid");
                    nofind = false;
                }
                rs.close();
                getps.close();
            }
            if ((cid > 0) && (aid > 0)) {
                PreparedStatement ps = c.prepareStatement("UPDATE accounts SET loggedin = 0 where id = ?");
                ps.setInt(1, aid);
                ps.executeUpdate();
                ps.close();
            }

            c.close();
            if (nofind) {
                JOptionPane.showMessageDialog(this, "操作失败，没有这个玩家名");
            } else {
                JOptionPane.showMessageDialog(this, "操作成功。");
            }
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
    }

    private void jButton_ClosedServerActionPerformed(ActionEvent evt) {
        try {
            this.minutesLeft = Integer.parseInt(this.jTextField2.getText());

            if ((this.ts == null) && ((t == null) || (!t.isAlive()))) {
                JOptionPane.showMessageDialog(this, "正在关闭中。");
                t = new Thread(ShutdownServer.getInstance());
                this.ts = Timer.EventTimer.getInstance().register(new Runnable() {
                    public void run() {
                        if (ServerControl.this.minutesLeft == 0) {
                            ShutdownServer.getInstance().shutdown();
                            ServerControl.t.start();
                            ServerControl.this.ts.cancel(false);
                            return;
                        }
                        World.Broadcast.broadcastMessage(UIPacket.clearMidMsg());
                        World.Broadcast.broadcastMessage(UIPacket.getMidMsg("游戏将于 " + ServerControl.this.minutesLeft + " 分钟之后关闭维护.请玩家安全下线.", true, 0));
                        World.Broadcast.broadcastMessage(MaplePacketCreator.serverNotice(0, " 游戏将于 " + ServerControl.this.minutesLeft + " 分钟之后关闭维护.请玩家安全下线."));
                        minutesLeft--;
                    }
                }, 60000L);
            } else {
                JOptionPane.showMessageDialog(this, "正在关闭中。请留意服务端的提示。");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) {
        try {
            for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(ServerControl.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            Logger.getLogger(ServerControl.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(ServerControl.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedLookAndFeelException ex) {
            Logger.getLogger(ServerControl.class.getName()).log(Level.SEVERE, null, ex);
        }

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                new ServerControl().setVisible(true);
            }
        });
    }

    public final void WindowMid() {
        Toolkit kit = Toolkit.getDefaultToolkit();
        Dimension screenSize = kit.getScreenSize();
        int screenWidth = screenSize.width / 2;
        int screenHeight = screenSize.height / 2;
        int height = getHeight();
        int width = getWidth();
        setLocation(screenWidth - width / 2, screenHeight - height / 2);
    }
}
